home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
cli
/
mx2src.arc
/
ATOMIC.MOD
< prev
next >
Wrap
Text File
|
1989-01-05
|
31KB
|
968 lines
(* Copyright 1987,1988 fred brooks LogicTek *)
(* *)
(* *)
(* First Release 12/8/87-FGB *)
(* *)
(* Modified TermProcess to also kill all the children processes *)
(* of the parent. Changed FindProcess not to find zombies *)
(* 12/11/87-FGB *)
(* *)
(* Added variable parm to StartProcess to pass info to process *)
(* in currentprocess.gemsave[15] 1/1/88-FGB *)
(* The PID of the new process will be returned in variable parm *)
(* 2/24/88-FGB *)
(* *)
(* Added DozeProcess to allow timed a sleep of processes *)
(* 2/21/88-FGB *)
(* *)
(* Remove monitor priority. Each routine the switches processes *)
(* must be protected from all interrupts by the IntEnd and *)
(* IntBegin calls. If this is not done correctly the system *)
(* system will bomb. 4/4/88-FGB *)
(* *)
(*$T-,$S-,$A+ *)
IMPLEMENTATION MODULE ATOMIC;
FROM SYSTEM IMPORT ADR,TSIZE,
CODE,SETREG,ADDRESS,REGISTER;
FROM NEWSYS IMPORT NEWPROCESS,PROCESS,TRANSFER,IOTRANSFER;
FROM XBIOS IMPORT SuperExec;
FROM BitStuff IMPORT LAnd;
FROM GEMDOS IMPORT GetTime,GetDate,Super;
FROM Storage IMPORT ALLOCATE,DEALLOCATE;
FROM Strings IMPORT String;
TYPE workspace = ARRAY [0..254] OF CARDINAL;
savetype = POINTER TO ARRAY [0..22] OF CARDINAL;
sigs = (sleep,wakeup,terminate,trace,routine,
program,wait,gem,tos);
CPFlagtype = SET OF sigs;
CPFlagptrtype = POINTER TO CPFlagtype;
CONST trapvec = 110H; (* vector on IOTRANSFER *)
offsetvec = 140H; (* offset IOTRANSFER vector *)
intnum = 4; (* interrupt number on MFP *)
VAR s0,s1,s2,schedproc,s,
initproc,lastproc : SIGNAL;
kin : ARRAY [0..32] OF INTEGER;
wsp0,wsp1,wsp2,wsp3 : workspace;
wsp,bios : ADDRESS;
etimer [400H] : ADDRESS;
biospointer [4a2H] : ADDRESS;
ptermvec [408H] : ADDRESS;
trap [trapvec] : ADDRESS;
memtop [436H] : ADDRESS;
flock [43eH] : CARDINAL;
hz200 [4baH] : LONGCARD;
temphz200,TICKS : LONGCARD;
sysvector [144H] : POINTER TO sysvariable;
accsuperstack : ADDRESS;
sysvar : sysvariable;
linea [28H] : ADDRESS;
gemdos [84H] : ADDRESS;
gsxgem [88H] : ADDRESS;
tbios [0b4H] : ADDRESS;
xbios [0b8H] : ADDRESS;
linef [2cH] : ADDRESS;
level2 [68H] : ADDRESS;
level4 [70H] : ADDRESS;
shellp [4F6H] : ADDRESS;
oldtrap,oldtermvec : ADDRESS;
OldEtimer,sspval : ADDRESS;
p,cotick,x,t,temp : PROCESS;
processesid,I : INTEGER;
zombie : BOOLEAN;
children,highpri : INTEGER;
savefrom,saveto : savetype;
CPFlagptr : CPFlagptrtype;
(* -------------- BEGIN -------------- *)
PROCEDURE StartProcess(VAR P : PROC;
VAR n : LONGCARD;
VAR priority : INTEGER;
VAR pn : String;
VAR parm : ADDRESS);
BEGIN
IntEnd;
SuperExec(UpdatecurrentProc);
ALLOCATE(wsp,n);
IF wsp=NIL THEN
currentprocess^.errno:=12;
IntBegin;
RETURN;
END;
DEC(sysmemsize,n);
s1:=currentprocess;
s0:=currentprocess;
IF processesid>0 THEN (* search only after setup of SCHED *)
s0:=schedproc; (* set to sched process *)
LOOP (* find zombie process *)
s0:=s0^.next;
IF s0^.pid=1 THEN (* zombie not found in list *)
EXIT;
END;
FindZombieProcess(zombie);
IF zombie THEN EXIT END;
END;
END; (* if processesid>1 *)
IF zombie THEN
currentprocess:=s0;
ELSE
ALLOCATE(currentprocess,TSIZE(ProcessDescriptor));
IF currentprocess=NIL THEN
s1^.errno:=12;
IntBegin;
RETURN;
END;
DEC(sysmemsize,TSIZE(ProcessDescriptor));
INC(processesid);
currentprocess^.pid:=processesid;
currentprocess^.next:=initproc; lastproc^.next:=currentprocess;
lastproc:=currentprocess;
END;
WITH currentprocess^ DO
name:=pn;
ppid:=request.pid;
ready:=TRUE; active:=TRUE;
tick:=0;
IF priority<1 THEN priority:=1 END;
IF priority>10 THEN priority:=10 END;
pri:=priority;
misc[0]:=pri;
IF pri>highpri THEN highpri:=pri END;
GetTime(time);
GetDate(date);
gemsave[13]:=0; (* set timer to zero *)
gemsave[14]:=0; (* set all flags to zero *)
gemsave[15]:=parm;
parm:=ADDRESS(currentprocess^.pid);
Iport:=s1^.Iport;
Oport:=s1^.Oport;
END;
IF currentprocess^.pid>1 THEN
FindProcess(request.pid,s2);
s2^.return:=currentprocess^.pid;
ELSE
currentprocess^.return:=0;
END;
SuperExec(SetSlice);
currentprocess^.slice:=temphz200;
currentprocess^.wsp:=wsp;
currentprocess^.wspsize:=n;
NEWPROCESS(P,wsp,n,currentprocess^.cor);
SuperExec(intbiosptr);
s1^.errno:=0;
INC(contextswitch); (* update switch counter *)
TRANSFER(s1^.cor,currentprocess^.cor);
IntBegin;
END StartProcess;
PROCEDURE TermProcess(VAR id: INTEGER);
BEGIN
IF id<2 THEN RETURN END;
IntEnd;
FindProcess(id,s2);
IF s2=NIL THEN
currentprocess^.errno:=3;
IntBegin;
RETURN;
END;
currentprocess^.errno:=0;
s2^.active:=FALSE; (* set flag *)
IF s2^.wsp#NIL THEN
DEALLOCATE(s2^.wsp,s2^.wspsize);
INC(sysmemsize,s2^.wspsize);
END;
s2^.wsp:=NIL; (* set TO NIL to make zombie process *)
s0:=currentprocess; (* set to the parent process *)
kin[0]:=id;
REPEAT (* loop thru process list and find all related processes *)
FindChildProcess(kin[0],s1);
WHILE s1#NIL DO
INC(children);
kin[children]:=s1^.pid;
s1^.active:=FALSE; (* set flag *)
s1^.gemsave[14]:=0; (* reset all flags *)
IF s1^.wsp#NIL THEN
DEALLOCATE(s1^.wsp,s1^.wspsize);
INC(sysmemsize,s1^.wspsize);
END;
s1^.wsp:=NIL; (* set TO NIL to make zombie process *)
currentprocess:=s1; (* set currentprocess to terminated *)
SuperExec(IncSlice); (* update cpu time for terminated *)
FindChildProcess(kin[0],s1